<?php

defined('_JEXEC') or die('Restricted access');

class User extends Controller {

    protected $_create_user_form_name = 'create_user';
    protected $_edit_user_form_name = 'edit_user';
    protected $_delete_users_form_name = 'deleteUsers_Form';

    protected $_username_allowed_chars = array(
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_');
    protected $_username_min_lenght = 4;
    protected $_username_max_lenght = 16;
    protected $_password_allowed_chars = array(
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_', '@', '.', '-', '!', '#', '$', '%', '^', '&', '*', '(', ')', '=', '+', '[',
        ']', '{', '}', ':', '<', '>');
    protected $_password_min_lenght = 8;
    protected $_password_max_lenght = 255;
    protected $_email_allowed_chars = array(
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_', '@', '.', '-');
    protected $_email_min_lenght = 6;
    protected $_email_max_lenght = 255;
    
    public function __construct() {
        parent::__construct();
        Session::init();
        $logged = Session::get('loggedIn');

        //here check if user is logged in AND that belongs to ADMIN group !!!!!!
        // ASK Database for the abeove data (group, etc.) !!!!
//        if ($logged == false) {
//            Session::destroy();
//            header('location: ../login');
//            exit;
//        }
    }

    public function index() {
//        $this->view->userList = $this->model->userList();
        $this->view->render('user/index');
    }

    public function getUsersList($from_to_Record='1_20'){
        //todo: if user doesn't have access to this function, return "permision denied"....
        //todo: pagination: $from_to_Record...

        $from_db = $this->model->userList__withoutPasswords();
        //is $from_db an array ??
        // should I perform other checks??
        if (!is_array($from_db)){
            Tools::sendToClient_JSON(array('response' =>'NOK', 'errors'=>array("Error 0x00DB0050: No responce from DB"), 'data'=>array()));
            return FALSE;
        }
        
        $dataToReturn = array(
            "table_column_names"=> array("ID", "Username", "Email", "Date last access", "Date created", "Status"),
            "table_data"=> $from_db
        );
        
        Tools::sendToClient_JSON(array('response' =>'OK', 'errors'=>array(), 'data'=>$dataToReturn));
        return TRUE;
    }
    
    public function create() {
        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
            Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('REQUEST_METHOD must be POST')));
            return false;
        }

        $validation_rules = array(
            'form_name' => array(
                'optional' => array(
                    'value' => FALSE,
                    'custom_msg' => "Error:0x0C100 :: Something is wrong with the submited form, please contact the Site's Administrator." //Submited(posted) form's field <form_name> is missing 
                ),
                //'in'=>array($this->_create_user_form_name),
                'in_c' => array(
                    'value' => array($this->_create_user_form_name),
                    'custom_msg' => "Error:0x0C101 :: Something is wrong with the submited form, please contact the Site's Administrator." //Submited(posted) form's field <form_name> is wrong, must be equal to $this->_create_user_form_name
                ),
            ),
            'username' => array(
                'optional' => array(
                    'value' => FALSE,
                    'custom_msg' => 'Username is required'
                ),
                'min_length_c' => array(
                    'value' => $this->_username_min_lenght,
                    'custom_msg' => "no less than " . $this->_username_min_lenght . " characters"
                ),
                'max_length_c' => array(
                    'value' => $this->_username_max_lenght,
                    'custom_msg' => "no more than " . $this->_username_max_lenght . " characters"
                ),
                'alphaNum_noCap_firstLetter' => true, // alpha/numeric, no capital letters, first char must be alpha (not numeric) 
            ),
            'password' => array(
                'optional' => array(
                    'value' => FALSE,
                    'custom_msg' => 'Password is required'
                ),
                'min_length_c' => array(
                    'value' => $this->_password_min_lenght,
                    'custom_msg' => "no less than " . $this->_password_min_lenght . " characters"
                ),
                'max_length_c' => array(
                    'value' => $this->_password_max_lenght,
                    'custom_msg' => "no more than " . $this->_password_max_lenght . " characters"
                ),
            ),
            'email' => array(
                'optional' => array(
                    'value' => FALSE,
                    'custom_msg' => 'Email is required'
                ),
                'min_length_c' => array(
                    'value' => $this->_email_min_lenght,
                    'custom_msg' => "no less than " . $this->_email_min_lenght . " characters"
                ),
                'max_length_c' => array(
                    'value' => $this->_email_max_lenght,
                    'custom_msg' => "no more than " . $this->_email_max_lenght . " characters"
                ),
                'email' => TRUE,
            ),
            'chk_group' => array(
                'optional' => TRUE,
                'onlyDigits' => true,
            ),
        );
        $validator = new formValidator($_POST, $validation_rules);

        if (!$validator->validate()) {
            Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => $validator->get_errors()));
            return FALSE;
        }

        if ($this->model->usernameExists($_POST['username'])) {
            Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array("Username already exists, please provide a different one")));
            return FALSE;
        }

        if ($this->model->emailExists($_POST['email'])) {
            Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array("Email already exists, please provide a different one")));
            return FALSE;
        }

        if (isset($_POST['chk_group']) && is_array($_POST['chk_group'])) {
            $grp_m = new Group_Model();
            $f_groups_ids = Tools::flattenArray($grp_m->getAllRecords_By("id"));
            foreach ($_POST['chk_group'] as $v) {
                if (!in_array($v, $f_groups_ids)) {
                    Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array("GroupID [" . $v . "] does not exists in database")));
                    return FALSE;
                }
            }
            unset($grp_m, $f_groups_ids, $validator);
            $newUser_groups = $_POST['chk_group'];
        } else {
            $newUser_groups = array(0 => DEFAULT_USER_GROUP);
        }

        $data = array();
        $data['username'] = $_POST['username'];
        $data['password'] = md5($_POST['password']);
        $data['email'] = $_POST['email'];
        $data['date_last_access'] = date("Y-m-d H:i:s", time()); //date-time formated as MySQL DATETIME
        $data['date_created'] = date("Y-m-d H:i:s", time()); //date-time formated as MySQL DATETIME
        $data['status'] = $_POST['status'];
        
        $new_userID = $this->model->createNewUser($data);
        if ($new_userID === FALSE) {
            Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('Server Error:: cannot create New User')));
            return false;
        }

        foreach ($newUser_groups as $group_id) {
            $tt = $this->model->assignUserTo_aGroup_byID($new_userID, $group_id);
        }

        Tools::sendToClient_JSON(array('response' => 'OK', 'redirect' => URL . 'user', 'errors' => array()));
        return TRUE;
    }

    public function edit($id=NULL) {
//        if (NULL===$id) throw new Exception('Missing User id from url, cannot edit user.');
//        if (!is_numeric($id)) throw new Exception('User id must be a number, cannot edit user.');
//        
//        $ur = $this->model->userSingleList($id);
//        if (empty($ur)){throw new Exception('User id does not exists');}
//        
//        $data = array();
//        $data['id'] = $id;
//        $data['username'] = $_POST['username'];
//        $data['password'] = $_POST['password'];
//        $data['email'] = $_POST['email'];
//        
        //put here the group(s) of the edited user
        // @TODO: Do your error/validiation checking for the above data!
        // check here if username and email already exists. username and email are UNIQUE fields in user table
        //$this->model->editSave($data);
        // also save the user's group
        //header('location: ' . URL . 'user');
    }

    public function delete() {
        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
            Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('REQUEST_METHOD must be POST'), 'data'=>array()));
            return false;
        }
        
        $validation_rules = array(
            'form_name' => array(
                'optional' => array(
                    'value' => FALSE,
                    'custom_msg' => "Error:0x0F100 :: Something is wrong with the submited form, please contact the Site's Administrator." //Submited(posted) form's field <form_name> is missing 
                ),
                'in_c' => array(
                    'value' => array($this->_delete_users_form_name),
                    'custom_msg' => "Error:0x0F101 :: Something is wrong with the submited form, please contact the Site's Administrator." //Submited(posted) form's field <form_name> is wrong, must be equal to $this->_delete_users_form_name
                ),
            ),
            'ids_to_delete'=> array(
                'optional' => array(
                    'value' => FALSE,
                    'custom_msg' => "Error:0x0F200 :: Something is wrong with the submited form, please contact the Site's Administrator." //Submited(posted) form's field <ids_to_delete> is missing 
                ),
            ),
        );
        $validator = new formValidator($_POST, $validation_rules);

        if (!$validator->validate()) {
            Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => $validator->get_errors(), 'data'=>array()));
            return FALSE;
        }

        $a = json_decode($_POST['ids_to_delete'], TRUE);
        if (!is_array($a)){
            Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('Delete Users Form: Field [ids_to_delete] is not in the right format'), 'data'=>array()));
            return;
        }
        
        //empty array ??
        if (count($a)==0){
            Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('Delete Users Form: Field [ids_to_delete] is empty...'), 'data'=>array()));
            return;
        }
        
        if (empty($a)){
            Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('Delete Users Form: Field [ids_to_delete] is empty...'), 'data'=>array()));
            return;
        }
        
        foreach ($a as $id) {
            if (!Tools::hasOnlyDigits($id)){
                Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('Delete Users Form: Field [ids_to_delete]: one of the array element is not in the right format. It must be a number.'), 'data'=>array()));
                return;
            }
            if (!is_numeric($id)){
                Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('Delete Users Form: Field [ids_to_delete]: one of the array element is not in the right format. It must be a number.'), 'data'=>array()));
                return;
            }
        
            // does user_id exists ? 
            $ur = $this->model->userSingleList($id);

            // empty or count ?????
            if (empty($ur)){
                Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('User ID was not found in database, cannot delete user'), 'data'=>array()));
                return false;
            }
            
            //todo: also check if we try to delete us, if our id is in the list, cause we should not allow us to delete our account....
        }
        
        //todo: change it to "delete from tableName where id in (:ids)" 
        // where :ids is a variable with the ids separated with commas... 
        
        foreach ($a as $id) {
            $r = $this->model->delete($id);
            if ($r===FALSE){
                Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('Something went wrong, cannot delete user. Please contact Site\'s Admin'), 'data'=>array()));
                return false;
            }
            // $this->model->delete($id) should delete just one record...
            if ($r!=1){
                Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('Something went wrong, cannot delete user. Please contact Site\'s Admin'), 'data'=>array()));
                return false;
            }

            //also delete the records, of this user_id, from the user_group relations table
            $ug = new User_group_Model();
            $e = $ug->delete_All("`user_id` = ".$id); //deletes multiple records...
            if ($e===FALSE){
                Tools::sendToClient_JSON(array('response' => 'NOK', 'errors' => array('Something went wrong, cannot delete user. Please contact Site\'s Admin'), 'data'=>array()));
                return false;
            }
        }
        
        unset($ug, $e, $r, $ur);
        Tools::sendToClient_JSON(array('response' => 'OK', 'errors' => array(), 'data'=>array()));
        return TRUE;
    }

}